package com.itlong.cloud.controller.system;

import com.itlong.cloud.POJO.DTO.property.PropertyRepairGetRepairsByPageDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyRepairHandleDTO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.property.PropertyRepairGetOneVO;
import com.itlong.cloud.POJO.VO.property.PropertyRepairGetRepairsByPageVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.AuthAccessRequired;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.FileCatalogEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.PropertyErrorCodeEnum;
import com.itlong.cloud.noncore.property.IPropertyRepairManageClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.apache.poi.hssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * <desc>
 *      物业报修管理控制器
 * </desc>
 *
 * @createDate 2018/08/14
 */
@RestController
@RequestMapping("/system/repair")
@RefreshScope
public class PropertyRepairController extends BaseController {

    private static final Logger LOG = LoggerFactory.getLogger(PropertyRepairController.class);

    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;

    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;

    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;

    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;

    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    @Autowired
    private IPropertyRepairManageClient iPropertyRepairManageClient;

    /**
     * <desc>
     *      分页获取报修管理信息，包含待受理、已受理、已完成、已取消
     * </desc>
     *
     * @param propertyRepairGetRepairsByPageDTO 查询参数
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/08/14
     */
    @ResponseBody
    @AuthAccessRequired
    @PostMapping(path = "getRepairsByPage")
    public Object getRepairsByPage(PropertyRepairGetRepairsByPageDTO propertyRepairGetRepairsByPageDTO){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyRepairGetRepairsByPageDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyRepairGetRepairsByPageDTO.class, request);
            // 判断参数合法性
            if (null == propertyRepairGetRepairsByPageDTO) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (StringUtils.isBlank(propertyRepairGetRepairsByPageDTO.getProjectId())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (propertyRepairGetRepairsByPageDTO.getRepairStatus() == null || StringUtils.isBlank(propertyRepairGetRepairsByPageDTO.getRepairStatus().toString())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            // 判断时间区间的合法性
            if (StringUtils.isNotBlank(propertyRepairGetRepairsByPageDTO.getStartTime()) && StringUtils.isNotBlank(propertyRepairGetRepairsByPageDTO.getEndTime())) {
                Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(propertyRepairGetRepairsByPageDTO.getStartTime());
                Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(propertyRepairGetRepairsByPageDTO.getEndTime());
                // 开始时间必须小于结束时间
                if (startTime.after(endTime)) {
                    return new MessageVO(PropertyErrorCodeEnum.TIME_AVAILABLE_ERR.getErrorCode());
                }
            }
            Page<PropertyRepairGetRepairsByPageVO> page = iPropertyRepairManageClient.getRepairsByPage(propertyRepairGetRepairsByPageDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), page);
        } catch (Exception e) {
            throw new DataAccessException("【物业-报修管理】获取分页列表失败",e);
        }
    }

    /**
     * <desc>
     *      导出报修单，包含待受理、已受理、已完成、返修处理
     * </desc>
     *
     * @param propertyRepairGetRepairsByPageDTO 查询参数
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/08/16
     */
    @ResponseBody
    @AuthAccessRequired
    @PostMapping(path = "exportRepairs")
    public Object exportRepairs(PropertyRepairGetRepairsByPageDTO propertyRepairGetRepairsByPageDTO){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyRepairGetRepairsByPageDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyRepairGetRepairsByPageDTO.class, request);
            // 判断参数合法性
            if (null == propertyRepairGetRepairsByPageDTO) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (StringUtils.isBlank(propertyRepairGetRepairsByPageDTO.getProjectId())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (propertyRepairGetRepairsByPageDTO.getRepairStatus() == null || StringUtils.isBlank(propertyRepairGetRepairsByPageDTO.getRepairStatus().toString())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            // 判断时间区间的合法性
            if (StringUtils.isNotBlank(propertyRepairGetRepairsByPageDTO.getStartTime()) && StringUtils.isNotBlank(propertyRepairGetRepairsByPageDTO.getEndTime())) {
                Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(propertyRepairGetRepairsByPageDTO.getStartTime());
                Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(propertyRepairGetRepairsByPageDTO.getEndTime());
                // 开始时间必须小于结束时间
                if (startTime.after(endTime)) {
                    return new MessageVO(PropertyErrorCodeEnum.TIME_AVAILABLE_ERR.getErrorCode());
                }
            }
            //定义表头
            String[] title;
            if (propertyRepairGetRepairsByPageDTO.getRepairStatus() == 1) {
                title = new String[]{"序号","报修单号","报修类型","报修描述","地址","报修人","联系电话","预约时间","报修时间"};
            } else if (propertyRepairGetRepairsByPageDTO.getRepairStatus() == 2) {
                title = new String[]{"序号","报修单号","报修类型","报修描述","地址","报修人","联系电话","受理人","状态","预约时间","受理时间"};
            } else if (propertyRepairGetRepairsByPageDTO.getRepairStatus() == 3) {
                title = new String[]{"序号","报修单号","报修类型","报修描述","地址","报修人","联系电话","受理人","预约时间","完成时间"};
            } else {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode());
            }
            List<PropertyRepairGetRepairsByPageVO> propertyRepairGetRepairsByPageVOS = iPropertyRepairManageClient.getAllRepairs(propertyRepairGetRepairsByPageDTO);
            if (propertyRepairGetRepairsByPageVOS == null || propertyRepairGetRepairsByPageVOS.isEmpty()) {
                return new MessageVO(PropertyErrorCodeEnum.EXPORT_DATA_EMPTY_ERR.getErrorCode());
            }
            short rowHeight= 420;
            //创建excel工作簿
            HSSFWorkbook workbook=new HSSFWorkbook();
            //创建工作表sheet并设置简单格式
            HSSFSheet sheet=workbook.createSheet();
            sheet.setDefaultColumnWidth(20);
            //创建第一行
            HSSFRow row=sheet.createRow(0);
            row.setHeight(rowHeight);
            HSSFCell cell=null;
            //插入第一行数据的表头
            for (int i = 0; i < title.length; i++) {
                cell = row.createCell(i);
                cell.setCellValue(title[i]);
            }
            //写入数据
            for (int repairIndex = 0; repairIndex < propertyRepairGetRepairsByPageVOS.size(); repairIndex++) {
                PropertyRepairGetRepairsByPageVO propertyRepairGetRepairsByPageVO = propertyRepairGetRepairsByPageVOS.get(repairIndex);
                int rowIndex = repairIndex + 1; //标题行
                HSSFRow dataRow = sheet.createRow(rowIndex);
                dataRow.setHeight(rowHeight);
                HSSFCell noteCell = dataRow.createCell(0);
                noteCell.setCellValue(rowIndex);
                noteCell = dataRow.createCell(1);
                noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getRepairNum());
                noteCell = dataRow.createCell(2);
                noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getRepairType() == 1 ? "个人设施" : "公共设施");
                noteCell = dataRow.createCell(3);
                noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getRepairDescription());
                noteCell = dataRow.createCell(4);
                noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getAddress());
                noteCell = dataRow.createCell(5);
                noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getAppUserName());
                noteCell = dataRow.createCell(6);
                noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getAppUserPhone());
                if (propertyRepairGetRepairsByPageDTO.getRepairStatus() == 1) {
                    noteCell = dataRow.createCell(7);
                    noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getAppointmentTime());
                    noteCell = dataRow.createCell(8);
                    noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getStatusTime());
                } else if (propertyRepairGetRepairsByPageDTO.getRepairStatus() == 2) {
                    noteCell = dataRow.createCell(7);
                    noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getAcceptPerson());
                    noteCell = dataRow.createCell(8);
                    noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getAcceptStatus() == 1 ? "正在处理" : "申请撤销");
                    noteCell = dataRow.createCell(9);
                    noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getAppointmentTime());
                    noteCell = dataRow.createCell(10);
                    noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getStatusTime());
                } else if (propertyRepairGetRepairsByPageDTO.getRepairStatus() == 3) {
                    noteCell = dataRow.createCell(7);
                    noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getAcceptPerson());
                    noteCell = dataRow.createCell(8);
                    noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getAppointmentTime());
                    noteCell = dataRow.createCell(9);
                    noteCell.setCellValue(propertyRepairGetRepairsByPageVO.getStatusTime());
                }
            }
            String fileName = String.format("%s_RepairInfo_%s.xls",
                    propertyRepairGetRepairsByPageDTO.getProjectId(),
                    DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS"));
            fileName = URLEncoder.encode(fileName, "UTF-8");
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            workbook.write(os);
            byte[] content = os.toByteArray();
            InputStream exportFileStream = new ByteArrayInputStream(content);
            String exportfileUrl = uploadFile(exportFileStream,fileName);
            if (StringUtils.isBlank(exportfileUrl)){
                return new MessageVO(PropertyErrorCodeEnum.PROJECT_EXPORT_FILE_SAVE_ERR.getErrorCode());
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), (Object) exportfileUrl);
        } catch (Exception e) {
            throw new DataAccessException("【物业-报修管理】导出报修单失败",e);
        }
    }

    /**
     * <desc>
     *      Ftp上传文件，返回Url.
     * </desc>
     *
     * @param inputStream 文件流
     * @param fileName 文件名称
     * @return 文件上传成功后会返回Url,否则返回空
     * @author wangzhi
     * @createDate 2018/08/16
     */
    private String uploadFile(InputStream inputStream, String fileName) throws IOException {
        String fileUrl = "";
        String fileType = StringHandlerUtil.copySubStr(fileName, fileName.lastIndexOf('.') + 1, fileName.length());
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                inputStream,
                fileType,
                FILE_ACCESS_URL,
                FileCatalogEnum.PROPERTYREPAIR_FILE.getType()
        );
        Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
        Boolean returnCode = (Boolean)resultMap.get("returnCode");
        if (returnCode == false){
            return fileUrl;
        }
        fileUrl = resultMap.get("accessPath").toString();
        return fileUrl;
    }

    /**
     * <desc>
     *      获取单个报修信息
     * </desc>
     *
     * @param repairId 报修id
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/08/14
     */
    @ResponseBody
    @PostMapping(path = "getOneRepair")
    @AuthAccessRequired
    public Object getOneRepair(String repairId){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            repairId = request.getAttribute("repairId") == null ? null : request.getAttribute("repairId").toString();
            if (StringUtils.isBlank(repairId)) {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode());
            }
            PropertyRepairGetOneVO propertyRepairGetOneVO = iPropertyRepairManageClient.getOneRepair(repairId);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),propertyRepairGetOneVO);
        } catch (Exception e) {
            throw new DataAccessException("【物业-报修管理】获取单个报修信息失败",e);
        }
    }

    /**
     * <desc>
     *      待受理页面处理操作
     * </desc>
     *
     * @param propertyRepairHandleDTO 报修信息各流程处理DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/08/15
     */
    @ResponseBody
    @AuthAccessRequired
    @PostMapping(path = "acceptRepair")
    @LoggerInfo(operateDesc = LogDescConstant.REPAIR_ACCEPT_LOG_DESC)
    public Object acceptRepair(PropertyRepairHandleDTO propertyRepairHandleDTO){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyRepairHandleDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyRepairHandleDTO.class, request);
            if (propertyRepairHandleDTO == null || StringUtils.isBlank(propertyRepairHandleDTO.getServicemanUserId())
                    || StringUtils.isBlank(propertyRepairHandleDTO.getServicemanPhoneNum()) || StringUtils.isBlank(propertyRepairHandleDTO.getRepairId())
                    || StringUtils.isBlank(propertyRepairHandleDTO.getProjectId())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            // 校验手机号码的合法性
            String phoneNum = propertyRepairHandleDTO.getServicemanPhoneNum();
            String regex = "^1[3|4|5|6|7|8|9]\\d{9}$";
            if (phoneNum.length() != 11 || !Pattern.compile(regex).matcher(phoneNum).matches()) {
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_PHONENUM_ERR.getErrorCode());
            }
            Integer intRes = iPropertyRepairManageClient.acceptRepair(propertyRepairHandleDTO);
            if (intRes == -1) {
                return new MessageVO(PropertyErrorCodeEnum.REPAIR_STATUS_HAS_MODIFIED.getErrorCode());
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业-报修管理】待受理状态数据处理操作失败",e);
        }
    }

    /**
     * <desc>
     *      已受理页面撤销操作
     * </desc>
     *
     * @param propertyRepairHandleDTO 报修信息各流程处理DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/08/15
     */
    @ResponseBody
    @PostMapping(path = "cancelRepair")
    @LoggerInfo(operateDesc = LogDescConstant.REPAIR_CANCEL_LOG_DESC)
    public Object cancelRepair(PropertyRepairHandleDTO propertyRepairHandleDTO){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyRepairHandleDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyRepairHandleDTO.class, request);
            if (propertyRepairHandleDTO == null || StringUtils.isBlank(propertyRepairHandleDTO.getRepairId()) || StringUtils.isBlank(propertyRepairHandleDTO.getProjectId())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Integer intRes = iPropertyRepairManageClient.cancelRepair(propertyRepairHandleDTO);
            if (intRes == -1) {
                return new MessageVO(PropertyErrorCodeEnum.REPAIR_STATUS_HAS_MODIFIED.getErrorCode());
            }
            return new MessageVO(propertyRepairHandleDTO.getRepairId(),BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业-报修管理】已受理状态撤销操作失败",e);
        }
    }

    /**
     * <desc>
     *      已受理页面完成操作
     * </desc>
     *
     * @param propertyRepairHandleDTO 报修信息各流程处理DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/08/15
     */
    @ResponseBody
    @PostMapping(path = "completeRepair")
    @LoggerInfo(operateDesc = LogDescConstant.REPAIR_COMPLETE_LOG_DESC)
    public Object completeRepair(PropertyRepairHandleDTO propertyRepairHandleDTO){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyRepairHandleDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyRepairHandleDTO.class, request);
            if (propertyRepairHandleDTO == null || StringUtils.isBlank(propertyRepairHandleDTO.getRepairId()) || StringUtils.isBlank(propertyRepairHandleDTO.getProjectId())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Integer intRes = iPropertyRepairManageClient.completeRepair(propertyRepairHandleDTO);
            if (intRes == -1) {
                return new MessageVO(PropertyErrorCodeEnum.REPAIR_STATUS_HAS_MODIFIED.getErrorCode());
            }
            return new MessageVO(propertyRepairHandleDTO.getRepairId(),BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业-报修管理】已受理状态完成操作失败",e);
        }
    }

    /**
     * <desc>
     *      确认返修操作
     * </desc>
     *
     * @param propertyRepairHandleDTO 报修信息各流程处理DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/08/15
     */
    @ResponseBody
    @PostMapping(path = "reworkRepair")
    @LoggerInfo(operateDesc = LogDescConstant.REPAIR_REWORK_LOG_DESC)
    public Object reworkRepair(PropertyRepairHandleDTO propertyRepairHandleDTO){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyRepairHandleDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyRepairHandleDTO.class, request);
            if (propertyRepairHandleDTO == null || StringUtils.isBlank(propertyRepairHandleDTO.getRepairId()) || StringUtils.isBlank(propertyRepairHandleDTO.getProjectId())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Integer intRes = iPropertyRepairManageClient.reworkRepair(propertyRepairHandleDTO);
            if (intRes == -1) {
                return new MessageVO(PropertyErrorCodeEnum.REPAIR_STATUS_HAS_MODIFIED.getErrorCode());
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业-报修管理】确认返修操作失败",e);
        }
    }

    /**
     * <desc>
     *      批量删除
     * </desc>
     *
     * @param repairIds 报修id，多个用英文","相连
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/08/15
     */
    @ResponseBody
    @PostMapping(path = "deleteRepairs")
    @LoggerInfo(operateDesc = LogDescConstant.REPAIR_DELETE_LOG_DESC)
    @AuthAccessRequired
    public Object deleteRepairs(String repairIds){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            repairIds = request.getAttribute("repairIds") == null ? null : request.getAttribute("repairIds").toString();
            if (StringUtils.isBlank(repairIds)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            iPropertyRepairManageClient.deleteRepairs(repairIds);
            return new MessageVO(repairIds,BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业-报修管理】批量删除操作失败",e);
        }
    }

}
